package com.imooc.controller;

import com.google.gson.Gson;
import com.imooc.api.mq.RabbitMQSMSConfig;
import com.imooc.base.BaseInfoProperties;
import com.imooc.grace.result.GraceJSONResult;
import com.imooc.grace.result.ResponseStatusEnum;
import com.imooc.pojo.Users;
import com.imooc.pojo.bo.RegistLoginBO;
import com.imooc.pojo.mq.SMSContentQO;
import com.imooc.pojo.vo.UsersVO;
import com.imooc.service.UsersService;
import com.imooc.utils.GsonUtils;
import com.imooc.utils.IPUtil;
import com.imooc.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.UUID;

/**
 * @author 啊昌
 * @date 2025/9/10 22:17
 * PassportController 通信认证类
 *
 */
@RestController
@RequestMapping("passport")
@Slf4j
public class PassportController extends BaseInfoProperties {

	@Autowired
	private UsersService usersService;

	@Autowired
	private JWTUtils jwtUtils;

	@Autowired
	private RabbitTemplate rabbitTemplate;


	/**
	 * 获取短信验证码
	 *
	 * @param mobile      手机号码
	 * @param httpRequest HTTP请求对象，用于获取用户IP地址
	 * @return GraceJSONResult 统一返回结果，成功时返回ok，失败时返回错误信息
	 * @throws Exception 可能抛出的异常
	 *                   使用 SMSInterceptor 拦截器对短信进行了限制 -> redis缓存
	 */
	@PostMapping("/getSMSCode")
	public GraceJSONResult getSMSCode(String mobile, HttpServletRequest httpRequest) throws Exception {
		//1. 继续判空
		if (StringUtils.isBlank(mobile)) {
			// isBlank 能对空格进来检测
			return GraceJSONResult.errorMsg("手机号不能为空");
		}
		//2. 对ip进行封禁 限制用户只能在60s以内获得一次验证码
		String userIp = IPUtil.getRequestIp(httpRequest); // 获取用户的ip
		redis.setnx60s(MOBILE_SMSCODE + ":" + userIp, mobile); // todo 锁操作
		//3.生成六位数的验证码
		String code = (int) ((Math.random() * 9 + 1) * 100000) + "";
		//4.将验证码存储在redis
		redis.set(MOBILE_SMSCODE + ":" + mobile, code, 60 * 30); //验证码有效期 30分钟
		log.info("验证码为：{}", code);
		//保证短信的可靠性-> 使用RabbitMQ发送消息
		SMSContentQO contentQO = new SMSContentQO();
		contentQO.setMobile(mobile);
		contentQO.setContent(code);

		// 顺序 生产者 -> 通过 Channel -> 交换机 -> 队列 -> Channel -> 消费者



		//确认消息是否到达交换机
//		rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
//						/**
//			 * 确认消息发送状态的回调方法
//			 *
//			 * @param correlationData 消息关联数据，用于标识消息的唯一性
//			 * @param ack 消息确认标志，true表示消息被成功接收，false表示消息发送失败
//			 * @param cause 失败原因，当ack为false时，此参数包含具体的失败原因描述
//			 */
//			@Override
//			public void confirm(CorrelationData correlationData, boolean ack, String cause) {
//				log.info("进入confirm");
//				if (ack) {
//					log.info("交换机成功接收到消息~~ {}", cause);
//				} else {
//					log.info("交换机接收消息失败~~失败原因： {}", cause);
//				}
//			}
//
//		});

		//交换机路由到队列是否成功
//		rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
//			@Override
//			public void returnedMessage(ReturnedMessage returned) {
//				log.info("进入return");
//                log.info("returnedMessage ,{}",returned.toString());
//			}
//		});

		rabbitTemplate.convertAndSend(
				RabbitMQSMSConfig.SMS_EXCHANGE,
				RabbitMQSMSConfig.ROUTING_KEY_SMS_SEND_LOGIN,
				GsonUtils.object2String(contentQO),
				new CorrelationData(UUID.randomUUID().toString()));

		HashMap<Object, Object> map = new HashMap<>();
		map.put("验证码", code);
		return GraceJSONResult.ok(map);
	}


	@PostMapping("/login")
	public GraceJSONResult login(@RequestBody @Valid RegistLoginBO registLoginBO, HttpServletRequest httpRequest) throws Exception {
		String mobile = registLoginBO.getMobile();
		String smsCode = registLoginBO.getSmsCode();

		//验证码验证
		String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
		if (StringUtils.isBlank(redisCode)) {
			// 验证码不正确
			return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
		}
		if (!redisCode.equals(smsCode)) {
			// 验证码不正确
			return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
		}
		//从数据库查询这个手机号 是否是注册用户还是正常登录用户
		Users users = usersService.queryMobileIsExist(mobile);
		if (users == null) {
			// 表示这个用户是注册用户
			users = usersService.createUsers(mobile);
		}
		// 表示这个用户是正常登录用户
		//生成token
		String jwt = jwtUtils.createJWTWithPrefix(new Gson().toJson(users),TOKEN_USER_PREFIX);
		// 将缓存的验证码删除 防止再次使用
		// 将用户信息和token 返回给前端
		UsersVO usersVO = new UsersVO();
		BeanUtils.copyProperties(users, usersVO);
		usersVO.setUserToken(jwt);
		redis.del(MOBILE_SMSCODE + ":" + mobile);
		return GraceJSONResult.ok(usersVO);
	}

	@PostMapping("/logout")
	public GraceJSONResult logout(@RequestParam String userId, HttpServletRequest httpRequest) throws Exception {
		redis.del(REDIS_USER_TOKEN+":"+userId);
		return GraceJSONResult.ok();
	}
}
